<?php
/**	
*	FILENAME: 		/libraries/mynova.php
*	DESCRIPTION:	This library that uses the PHP Snoopy library to interact with Villanova's MyNova system.
*	AUTHOR:			Casey Burkhardt
*	VERSION:		1.0.0
*	LAST MODIFIED:	12/30/2009
**/

/**
	THIS SCRIPT IS UNSTABLE AND SITLL UNDER DEVELOPMENT.
	ITS USE IS EXPERIMENTAL AND SHOULD NOT BE USED IN PRODUCTION AT THIS TIME.
**/
die();

require_once($_SERVER['DOCUMENT_ROOT'] . "/libraries/Snoopy.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/config/environment.php");

function parseCookie($val) {
	$equalsSign = strpos($val, "=");
	$cookieName = substr($val, strlen("Set-Cookie: "), $equalsSign - strlen("Set-Cookie: "));
	$semiColon = strpos($val, ";");
	$cookieValue = substr($val, $equalsSign + 1, $semiColon - $equalsSign - 1);
	$result[$cookieName] = $cookieValue;
	return $result;
}

/**	
*	DESCRIPTION:	Creates a valid MyNova authenticated session.
**/
function createMyNovaSession($userName, $password) {

	// We start by posting the user supplied login information to the MyNova Login Form.
	// Create a new instance of Snoopy, the page fetching / parsing engine.
	$loginPage = new Snoopy;
	
	// Set a timeout, in case this thing doesn't work
	$loginPage -> read_timeout = 5;
	
	// We will need to fetch pages using HTTPS, so we must point Snoopy to our instance of cURL.
	// This information is stored in our environment configuration.
	$loginPage -> curl_path = getCurlPath();
	
	// Set up appropriate Header Types, We'll reuse these...
	$rawHeaders["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
	$rawHeaders["Accept-Language"] = "en-us,en;q=0.5";
	$rawHeaders["Accept-Encoding"] = "gzip,deflate";
	$rawHeaders["Accept-Charset"] = "ISO-8859-1,utf-8;q=0.7,*;q=0.7";
	$rawHeaders["Keep-Alive"] = "300";
	$rawHeaders["Connection"] = "keep-alive";
	
	$loginPage -> rawheaders = $rawHeaders;
		
	if ($loginPage -> fetch("https://novanet.villanova.edu/cp/home/displaylogin")) {
		while(list($key,$val) = each($loginPage->headers)) {
			if(strpos($val, "Set-Cookie: ") !== FALSE) {
				// If the header contains a cookie, set that cookie
				$loginPage -> cookies = array_merge($loginPage -> cookies, parseCookie($val));
			}
			echo $key.": ".$val."<br>\n";
		}
		echo "<p>\n";
//		echo "<PRE>".htmlspecialchars($loginPage->results)."</PRE>\n";
	} else {
		echo "error fetching document: ".$loginPage->error."\n";
		die();
	}
	
	// Cookies will need to be carried over to the next request, so we'll store them here.
	$cookiesSoFar = $loginPage -> cookies;
	
	// Debugging
	echo "<br /><br />Cookies: <br />";
	print_r($cookiesSoFar);
	echo "<br /><br />";
	
	// Now we submit the login information.
	$loginSubmission = new Snoopy;
	$loginSubmission -> read_timeout = 5;
	$loginSubmission -> curl_path = getCurlPath();
	$loginSubmission -> cookies = $cookiesSoFar;
	$loginSubmission -> rawheaders = $rawHeaders;
		
	// Populate the data for the POST request.
	$submitVars["user"] = $userName;
	$submitVars["pass"] = $password;
	
	if ($loginSubmission -> submit("https://novanet.villanova.edu/cp/home/login", $submitVars)) {
		while(list($key,$val) = each($loginSubmission->headers)) {
			if(strpos($val, "Set-Cookie: ") !== FALSE) {
				// If the header contains a cookie, set that cookie
				$loginSubmission -> cookies = array_merge($loginSubmission -> cookies, parseCookie($val));
			}
			echo $key.": ".$val."<br>\n";
		}
		echo "<p>\n";
		echo "<PRE>".htmlspecialchars($loginSubmission->results)."</PRE>\n";
	} else {
		echo "error fetching document: ".$loginSubmission->error."\n";
		die();
	}
	
	// Cookies will need to be carried over to the next request, so we'll store them here.
	$cookiesSoFar = $loginSubmission -> cookies;
	
	// Debugging
	echo "<br /><br />Cookies: <br />";
	print_r($cookiesSoFar);
	echo "<br /><br />";
	
	// We'll now request the login success page.
	$authPage = new Snoopy;
	$authPage -> read_timeout = 5;
	$authPage -> curl_path = getCurlPath();
	$authPage -> cookies = $cookiesSoFar;
	$authPage -> rawheaders = $rawHeaders;
	
	if ($authPage -> fetch("https://novanet.villanova.edu/cps/welcome/loginok.html")) {
	while(list($key, $val) = each($authPage -> headers)) {
			if(strpos($val, "Set-Cookie: ") !== FALSE) {
				// If the header contains a cookie, set that cookie
				$authPage -> cookies = array_merge($authPage -> cookies, parseCookie($val));
			}
			echo $key . ": " . $val . "<br>\n";
		}
		echo "<p>\n";
		echo "<PRE>".htmlspecialchars($authPage->results)."</PRE>\n";
	} else {
		echo "error fetching document: ".$authPage->error."\n";
		die();
	}
	
	// Cookies will need to be carried over to the next request, so we'll store them here.
	$cookiesSoFar = $authPage -> cookies;
	
	// Debugging
	echo "<br /><br />Cookies: <br />";
	print_r($cookiesSoFar);
	echo "<br /><br />";
	
	// We'll now request the next login success page.
	$authPage2 = new Snoopy;
	$authPage2 -> read_timeout = 5;
	$authPage2 -> curl_path = getCurlPath();
	$authPage2 -> cookies = $cookiesSoFar;
	$authPage2 -> rawheaders = $rawHeaders;
	
	if ($authPage2 -> fetch("https://novanet.villanova.edu/cp/home/next")) {
	while(list($key, $val) = each($authPage2 -> headers)) {
			if(strpos($val, "Set-Cookie: ") !== FALSE) {
				// If the header contains a cookie, set that cookie
				$authPage2 -> cookies = array_merge($authPage2 -> cookies, parseCookie($val));
			}
			echo $key . ": " . $val . "<br>\n";
		}
		echo "<p>\n";
		echo "<PRE>".htmlspecialchars($authPage2->results)."</PRE>\n";
	} else {
		echo "error fetching document: ".$authPage2->error."\n";
		die();
	}
	
	// Cookies will need to be carried over to the next request, so we'll store them here.
	$cookiesSoFar = $authPage2 -> cookies;
	
	// Debugging
	echo "<br /><br />Cookies: <br />";
	print_r($cookiesSoFar);
	echo "<br /><br />";
	
	// We'll now request the next, and hopefully last login success page.
	$authPage3 = new Snoopy;
	$authPage3 -> read_timeout = 5;
	$authPage3 -> curl_path = getCurlPath();
	$authPage3 -> cookies = $cookiesSoFar;
	$authPage3 -> rawheaders = $rawHeaders;
	
	$submitMe["uP_root"] = "root";
	
	if ($authPage3 -> submit("https://novanet.villanova.edu/render.userLayoutRootNode.uP", $submitMe)) {
	while(list($key, $val) = each($authPage3 -> headers)) {
			if(strpos($val, "Set-Cookie: ") !== FALSE) {
				// If the header contains a cookie, set that cookie
				$authPage3 -> cookies = array_merge($authPage3 -> cookies, parseCookie($val));
			}
			echo $key . ": " . $val . "<br>\n";
		}
		echo "<p>\n";
		echo "<PRE>".htmlspecialchars($authPage3->results)."</PRE>\n";
	} else {
		echo "error fetching document: ".$authPage3->error."\n";
		die();
	}
	
	// Cookies will need to be carried over to the next request, so we'll store them here.
	$cookiesSoFar = $authPage3 -> cookies;
	
	// Debugging
	echo "<br /><br />Cookies: <br />";
	print_r($cookiesSoFar);
	echo "<br /><br />";
	
	// Finally, we'll request the courses page.
	$coursesPage = new Snoopy;
	$coursesPage -> read_timeout = 5;
	$coursesPage -> curl_path = getCurlPath();
	$coursesPage -> cookies = $cookiesSoFar;
	$coursesPage -> rawheaders = $rawHeaders;
	
	$submitMe["uP_root"] = "u12l1n30";
	$submitMe["padding"] = "true";	
	
	if ($coursesPage -> submit("https://novanet.villanova.edu/render.userLayoutRootNode.uP", $submitMe)) {
	while(list($key, $val) = each($coursesPage -> headers)) {
			if(strpos($val, "Set-Cookie: ") !== FALSE) {
				// If the header contains a cookie, set that cookie
				$coursesPage -> cookies = array_merge($coursesPage -> cookies, parseCookie($val));
			}
			echo $key . ": " . $val . "<br>\n";
		}
		echo "<p>\n";
		echo "<PRE>".htmlspecialchars($coursesPage->results)."</PRE>\n";
	} else {
		echo "error fetching document: ".$coursesPage->error."\n";
		die();
	}
	
	// Cookies will need to be carried over to the next request, so we'll store them here.
	$cookiesSoFar = $coursesPage -> cookies;
	
	// Debugging
	echo "<br /><br />Cookies: <br />";
	print_r($cookiesSoFar);
	echo "<br /><br />";
	
	// That course page actually works, but doesn't contain all the information we need.
	// We're giong to utilize UNIT's security loophole into NOVASIS to access the entire current course list.
	// Let's parse the URL that we actually want from the last response.
	
	$startIndex = strpos($coursesPage -> results, '<tr><td class="uportal-text"><TR><TD class="uportal-text"><a href="') + strlen('<tr><td class="uportal-text"><TR><TD class="uportal-text"><a href="');
	$endIndex = strpos($coursesPage -> results, '"', $startIndex);
	$url = substr($coursesPage -> results, $startIndex, $endIndex - $startIndex);
	$url = "https://novanet.villanova.edu/" . $url;
	
	// Now that we have the URL, we must seperate the GET Parameters out and pass them to the server in the final request as POST parameters.
	// There are only two paramaters, so it's easiest to parse by hand.
	// First Parameter
	$fPNStartIndex = strpos($url, "?") + 1;
	$fPNEndIndex = strpos($url, "=");
	$firstParamName = substr($url, $fPNStartIndex, $fPNEndIndex - $fPNStartIndex);
	echo "<br /><br />START: " . $fPNStartIndex . " END: " . $fPNEndIndex . " NAME WAS: " . $firstParamName;
	$fPVStartIndex = $fPNEndIndex + 1;
	$fPVEndIndex = strpos($url, "&", $fPVStartIndex);	
	$firstParamValue = substr($url, $fPVStartIndex, $fPVEndIndex - $fPVStartIndex);
	echo "<br /><br />START: " . $fPVStartIndex . " END: " . $fPVEndIndex . " NAME WAS: " . $firstParamValue;
	$finalPostVars[$firstParamName] = $firstParamValue;

	// Second Parameter
	$sPNStartIndex = strpos($url, "&", $fPVStartIndex) + 5;
	$sPNEndIndex = strpos($url, "=", $sPNStartIndex);
	$secondParamName = substr($url, $sPNStartIndex, $sPNEndIndex - $sPNStartIndex);
	echo "<br /><br />START: " . $sPNStartIndex . " END: " . $sPNEndIndex . " NAME WAS: " . $secondParamName;
	$sPVStartIndex = $sPNEndIndex + 1;
	$secondParamValue = substr($url, $sPVStartIndex);
	echo "<br /><br />START: " . $sPVStartIndex . " NAME WAS: " . $secondParamValue;
	$finalPostVars[$secondParamName] = $secondParamValue;
	
	echo "<br /><br />Request URL: " . $url;
	echo "<br /><br />Final Post Vars: <br />";
	print_r($finalPostVars);
	
	// Now remove all the parameters from the actual URL so it can be requested properly.
	$url = substr($url, 0, strpos($url, "?"));	
	echo "Shortened URL: " . $url;
	
	$coursesDetailPage = new Snoopy;
	$coursesDetailPage -> read_timeout = 5;
	$coursesDetailPage -> curl_path = getCurlPath();
	$coursesDetailPage -> cookies = $cookiesSoFar;
	$coursesDetailPage -> rawheaders = $rawHeaders;
	
	
	if ($coursesDetailPage -> submit($url, $finalPostVars)) {
	while(list($key, $val) = each($coursesDetailPage -> headers)) {
			if(strpos($val, "Set-Cookie: ") !== FALSE) {
				// If the header contains a cookie, set that cookie
				$coursesDetailPage -> cookies = array_merge($coursesDetailPage -> cookies, parseCookie($val));
			}
			echo $key . ": " . $val . "<br>\n";
		}
		echo "<p>\n";
		echo "<PRE>".htmlspecialchars($coursesDetailPage->results)."</PRE>\n";
	} else {
		echo "error fetching document: ".$coursesDetailPage->error."\n";
		die();
	}
	
	// Cookies will need to be carried over to the next request, so we'll store them here.
	$cookiesSoFar = $coursesDetailPage -> cookies;
	
	// Debugging
	echo "<br />THAT WAS IT<br />Cookies: <br />";
	print_r($cookiesSoFar);
	echo "<br /><br />";
	
}
?>